package com.ruoyi.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.bo.AttrBo;
import com.ruoyi.system.domain.bo.PStoreSeckillBo;
import com.ruoyi.system.domain.vo.PStoreProductCouponVo;
import com.ruoyi.system.domain.vo.PStoreProductVo;
import com.ruoyi.system.domain.vo.PStoreSeckillVo;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.IPStoreSeckillService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 商品秒杀产品Service业务层处理
 *
 * @author ruoyi
 * @date 2022-08-08
 */
@RequiredArgsConstructor
@Service
public class PStoreSeckillServiceImpl implements IPStoreSeckillService {

    private final PStoreSeckillMapper baseMapper;
    private final PStoreProductMapper productMapper;
    private final PStoreProductAttrValueMapper attrValueMapper;
    private final PStoreProductCouponMapper couponMapper;
    private final PAttrCommonMapper commonMapper;
    private final PAskCouponMapper askCouponMapper;

    /**
     * 查询商品秒杀产品
     */
    @Override
    public PStoreSeckillVo queryById(Long id){
        return baseMapper.selectFontVoById(id);
    }

    /**
     * 查询商品秒杀产品列表
     */
    @Override
    public TableDataInfo<PStoreSeckillVo> queryPageList(PStoreSeckillBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<PStoreSeckill> lqw = buildQueryWrapper(bo);
        Page<PStoreSeckillVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询商品秒杀产品列表
     */
    @Override
    public List<PStoreSeckillVo> queryList(PStoreSeckillBo bo) {
        LambdaQueryWrapper<PStoreSeckill> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<PStoreSeckill> buildQueryWrapper(PStoreSeckillBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<PStoreSeckill> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getProductId() != null, PStoreSeckill::getProductId, bo.getProductId());
        lqw.eq(StringUtils.isNotBlank(bo.getImage()), PStoreSeckill::getImage, bo.getImage());
        lqw.eq(StringUtils.isNotBlank(bo.getImages()), PStoreSeckill::getImages, bo.getImages());
        lqw.eq(StringUtils.isNotBlank(bo.getTitle()), PStoreSeckill::getTitle, bo.getTitle());
        lqw.eq(StringUtils.isNotBlank(bo.getInfo()), PStoreSeckill::getInfo, bo.getInfo());
        lqw.eq(bo.getPrice() != null, PStoreSeckill::getPrice, bo.getPrice());
        lqw.eq(bo.getCost() != null, PStoreSeckill::getCost, bo.getCost());
        lqw.eq(bo.getOtPrice() != null, PStoreSeckill::getOtPrice, bo.getOtPrice());
        lqw.eq(bo.getGiveIntegral() != null, PStoreSeckill::getGiveIntegral, bo.getGiveIntegral());
        lqw.eq(bo.getSort() != null, PStoreSeckill::getSort, bo.getSort());
        lqw.eq(bo.getStock() != null, PStoreSeckill::getStock, bo.getStock());
        lqw.eq(bo.getSales() != null, PStoreSeckill::getSales, bo.getSales());
        lqw.like(StringUtils.isNotBlank(bo.getUnitName()), PStoreSeckill::getUnitName, bo.getUnitName());
        lqw.eq(bo.getPostage() != null, PStoreSeckill::getPostage, bo.getPostage());
        lqw.eq(StringUtils.isNotBlank(bo.getDescription()), PStoreSeckill::getDescription, bo.getDescription());
        lqw.eq(bo.getStartTime() != null, PStoreSeckill::getStartTime, bo.getStartTime());
        lqw.eq(bo.getStopTime() != null, PStoreSeckill::getStopTime, bo.getStopTime());
        lqw.eq(bo.getStatus() != null, PStoreSeckill::getStatus, bo.getStatus());
        lqw.eq(bo.getIsPostage() != null, PStoreSeckill::getIsPostage, bo.getIsPostage());
        lqw.eq(bo.getIsDel() != null, PStoreSeckill::getIsDel, bo.getIsDel());
        lqw.eq(bo.getNum() != null, PStoreSeckill::getNum, bo.getNum());
        lqw.eq(bo.getIsShow() != null, PStoreSeckill::getIsShow, bo.getIsShow());
        lqw.eq(bo.getTimeId() != null, PStoreSeckill::getTimeId, bo.getTimeId());
        lqw.eq(bo.getTempId() != null, PStoreSeckill::getTempId, bo.getTempId());
        lqw.eq(bo.getWeight() != null, PStoreSeckill::getWeight, bo.getWeight());
        lqw.eq(bo.getVolume() != null, PStoreSeckill::getVolume, bo.getVolume());
        lqw.eq(bo.getQuota() != null, PStoreSeckill::getQuota, bo.getQuota());
        lqw.eq(bo.getQuotaShow() != null, PStoreSeckill::getQuotaShow, bo.getQuotaShow());
        lqw.eq(bo.getSpecType() != null, PStoreSeckill::getSpecType, bo.getSpecType());
        return lqw;
    }

    /**
     * 新增商品秒杀产品
     */
    @Override
    public Boolean insertByBo(PStoreSeckillBo bo) {
        PStoreSeckill add = BeanUtil.toBean(bo, PStoreSeckill.class);
        validEntityBeforeSave(add);
        return baseMapper.insert(add) > 0;
    }

    /**
     * 修改商品秒杀产品
     */
    @Override
    public Boolean updateByBo(PStoreSeckillBo bo) {
        PStoreSeckill update = BeanUtil.toBean(bo, PStoreSeckill.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(PStoreSeckill entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除商品秒杀产品
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Integer> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PStoreSeckillVo queryFontById(Long id) {
        PStoreSeckillVo pStoreSeckillVo = baseMapper.selectFontVoById(id);
        if (ObjectUtil.isEmpty(pStoreSeckillVo)) {
            throw new ServiceException("非法商品！");
        }

        long productId = pStoreSeckillVo.getProductId();
        if (ObjectUtil.isEmpty(productId)) {
            throw new ServiceException("非法商品！");
        }
        // 封装商品参数
        PStoreProductVo pStoreProductVo = productMapper.selectFontVoById(productId);
        if (ObjectUtil.isEmpty(pStoreProductVo)) {
            throw new ServiceException("非法商品！");
        }
        // 完善购物券
        List<PStoreProductCouponVo> couponVos = couponMapper.selectVoList(new LambdaQueryWrapper<PStoreProductCoupon>().eq(PStoreProductCoupon::getProductId, productId));
        if (CollectionUtil.isNotEmpty(couponVos)) {
            pStoreProductVo.setCouponIds(couponVos.stream().map(PStoreProductCouponVo::getIssueCouponId).collect(Collectors.toList()));
            List<PAskCoupon> pAskCoupons = askCouponMapper.selectList(new LambdaQueryWrapper<PAskCoupon>().in(PAskCoupon::getId, pStoreProductVo.getCouponIds()));
            pStoreProductVo.setCoupons(pAskCoupons);
        }
        // 完善商品规格
        List<PStoreProductAttrValue> attrValueVoList = attrValueMapper.selectLeftOssList(new LambdaQueryWrapper<PStoreProductAttrValue>().eq(PStoreProductAttrValue::getProductId, productId).eq(PStoreProductAttrValue::getType, "1"));
        pStoreProductVo.setAttrValue(attrValueVoList);
        // 设置规格回显数据结构
        List<PAttrCommon> attrCommons = commonMapper.selectList(new LambdaQueryWrapper<PAttrCommon>().eq(PAttrCommon::getProductId, productId));
        List<AttrBo> res = new ArrayList<>();
        attrCommons.forEach(e -> {
            AttrBo attrBo = new AttrBo();
            List<String> v = (List<String>) JSONUtil.parse(e.getStrValue());
            attrBo.setItem(v);
            attrBo.setName(e.getStrKey());
            res.add(attrBo);
        });
        // 填充秒杀
        pStoreProductVo.setAttr(res);
        pStoreSeckillVo.setProductVo(pStoreProductVo);

        return pStoreSeckillVo;
    }
}
